package com.zt.chatgpt.openai.service.channel.impl;

import com.alibaba.fastjson.JSON;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.zt.chatgpt.common.Constants;
import com.zt.chatgpt.domain.chat.ChatChoice;
import com.zt.chatgpt.domain.chat.ChatCompletionRequest;
import com.zt.chatgpt.domain.chat.ChatCompletionResponse;
import com.zt.chatgpt.domain.chat.Message;
import com.zt.chatgpt.openai.model.aggregates.ChatProcessAggregate;
import com.zt.chatgpt.openai.service.channel.OpenAiGroupService;
import com.zt.chatgpt.session.OpenAiSession;
import lombok.extern.slf4j.Slf4j;
import okhttp3.sse.EventSource;
import okhttp3.sse.EventSourceListener;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyEmitter;

import javax.annotation.Resource;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author: zt
 * @Description: ChatGPT 服务
 * @create: 2024-05-23 00:21
 */

@Slf4j
@Service
public class ChatGPTService implements OpenAiGroupService {

    @Resource
    protected OpenAiSession chatGPTOpenAiSession;


    /**
     * 处理聊天响应消息。
     *
     * @param chatProcess 包含聊天过程数据的聚合体，用于获取聊天过程中的消息和其他相关信息。
     * @param responseBodyEmitter 用于向客户端发送响应体的发射器。
     * @throws JsonProcessingException 当处理JSON数据时发生错误。
     */
    @Override
    public void doMessageResponse(ChatProcessAggregate chatProcess, ResponseBodyEmitter responseBodyEmitter) throws JsonProcessingException {
        // 1. 构造请求消息
        List<Message> messages = chatProcess.getMessages().stream()
                .map(entity -> Message.builder()
                        .content(entity.getContent())
                        .role(Constants.Role.valueOf(entity.getRole().toUpperCase()))
                        .name(entity.getName())
                        .build())
                .collect(Collectors.toList());

        // 2. 构造请求
        ChatCompletionRequest completionRequest = ChatCompletionRequest
                .builder()
                .stream(true)
                .messages(messages)
                .model(chatProcess.getModel())
                .build();

        // 3. 请求应答
        chatGPTOpenAiSession.chatCompletions(completionRequest, new EventSourceListener() {
            @Override
            public void onEvent(@NotNull EventSource eventSource, @Nullable String id, @Nullable String type, @NotNull String data) {
                // 1. 响应数据转化
                ChatCompletionResponse completionResponse = JSON.parseObject(data, ChatCompletionResponse.class);
                // 2. 获取响应信息
                List<ChatChoice> chatChoices = completionResponse.getChoices();

                for (ChatChoice chatChoice : chatChoices) {
//                    System.out.print(chatChoice.getDelta().getContent());
                    // 接受流式数据
                    Message delta = chatChoice.getDelta();
                    if (Constants.Role.ASSISTANT.getCode().equals(delta.getRole())) {
                        continue;
                    }


                    // 接受应答结束
                    String finishReason = chatChoice.getFinishReason();
                    if (StringUtils.isNoneBlank(finishReason) && "stop".equals(finishReason)) {
                        responseBodyEmitter.complete();
                        break;
                    }

                    // 发送信息
                    try {
                        responseBodyEmitter.send(delta.getContent());
                    } catch (Exception e) {
                        throw new RuntimeException(e);
                    }
                }
            }


        });
    }
}
